#include <buola/image/algorithm/gaussian_map.h>
#include "croot.h"
#include "cshadowdecoration.h"

#include <buola/gui/x11/cx11display.h>
#include <buola/gui/x11/cpixmap.h>
#include <buola/gl.h>
#include "cclient.h"

namespace buola { namespace bwm {

gl::CTexture CShadowDecoration::mTexture;
    
CShadowDecoration::CShadowDecoration(CClient *pClient)
    :   CDecoration(pClient)
{
}

CShadowDecoration::~CShadowDecoration()
{
}

void CShadowDecoration::CreateShadowTexture()
{
    if(mTexture) return;
    
    img::CImage_rgba8 lMap({40,40});
    gaussian_map(lMap,20,90);
    
    mTexture.Create2D(lMap);
}

void CShadowDecoration::Paint(const CRegion &pRegion,int pDesktop)
{
    if(!mTexture)
        CreateShadowTexture();

    CRect_i lRect=mClient->GetWholeRect(pDesktop);

    double l2R=2*20.0;
    CRect_d lIndent(25,15,25,25);
    CRect_d lIndentC=lIndent/l2R;

    CSize_d lS(l2R,l2R);
    
    if(2*lS.x>lRect.w())
        lS.x=lRect.w()/2.0;
    if(2*lS.y>lRect.h())
        lS.y=lRect.h()/2.0;
    CPoint_d lSC(lS.x/l2R,lS.y/l2R);
    
    mTexture.Bind();
    float lData[4*24];
    int i=0;
    lData[i++]=lRect.l;          //0
    lData[i++]=lRect.t;
    lData[i++]=0;
    lData[i++]=0;
    lData[i++]=lRect.l+lS.x;     //1
    lData[i++]=lRect.t;
    lData[i++]=lSC.x;
    lData[i++]=0;
    lData[i++]=lRect.r-lS.x;     //2
    lData[i++]=lRect.t;
    lData[i++]=lSC.x;
    lData[i++]=0;
    lData[i++]=lRect.r;          //3
    lData[i++]=lRect.t;
    lData[i++]=0;
    lData[i++]=0;
    lData[i++]=lRect.l;          //4
    lData[i++]=lRect.t+lS.y;
    lData[i++]=0;
    lData[i++]=lSC.y;
    lData[i++]=lRect.l+lIndent.l;//5
    lData[i++]=lRect.t+lS.y;
    lData[i++]=lIndentC.l;
    lData[i++]=lSC.y;
    lData[i++]=lRect.l+lIndent.l;//6
    lData[i++]=lRect.t+lIndent.t;
    lData[i++]=lIndentC.l;
    lData[i++]=lIndentC.t;
    lData[i++]=lRect.l+lS.x;     //7
    lData[i++]=lRect.t+lIndent.t;
    lData[i++]=lSC.x;
    lData[i++]=lIndentC.t;
    lData[i++]=lRect.r-lS.x;     //8
    lData[i++]=lRect.t+lIndent.t;
    lData[i++]=lSC.x;
    lData[i++]=lIndentC.t;
    lData[i++]=lRect.r-lIndent.r;//9
    lData[i++]=lRect.t+lIndent.t;
    lData[i++]=lIndentC.r;
    lData[i++]=lIndentC.t;
    lData[i++]=lRect.r-lIndent.r;//10
    lData[i++]=lRect.t+lS.y;
    lData[i++]=lIndentC.r;
    lData[i++]=lSC.y;
    lData[i++]=lRect.r;          //11
    lData[i++]=lRect.t+lS.y;
    lData[i++]=0;
    lData[i++]=lSC.y;
    lData[i++]=lRect.l;          //12
    lData[i++]=lRect.b-lS.y;
    lData[i++]=0;
    lData[i++]=lSC.y;
    lData[i++]=lRect.l+lIndent.l;//13
    lData[i++]=lRect.b-lS.y;
    lData[i++]=lIndentC.l;
    lData[i++]=lSC.y;
    lData[i++]=lRect.l+lIndent.l;//14
    lData[i++]=lRect.b-lIndent.b;
    lData[i++]=lIndentC.l;
    lData[i++]=lIndentC.b;
    lData[i++]=lRect.l+lS.x;     //15
    lData[i++]=lRect.b-lIndent.b;
    lData[i++]=lSC.x;
    lData[i++]=lIndentC.b;
    lData[i++]=lRect.r-lS.x;     //16
    lData[i++]=lRect.b-lIndent.b;
    lData[i++]=lSC.x;
    lData[i++]=lIndentC.b;
    lData[i++]=lRect.r-lIndent.r;//17
    lData[i++]=lRect.b-lIndent.b;
    lData[i++]=lIndentC.r;
    lData[i++]=lIndentC.b;
    lData[i++]=lRect.r-lIndent.r;//18
    lData[i++]=lRect.b-lS.y;
    lData[i++]=lIndentC.r;
    lData[i++]=lSC.y;
    lData[i++]=lRect.r;          //19
    lData[i++]=lRect.b-lS.y;
    lData[i++]=0;
    lData[i++]=lSC.y;
    lData[i++]=lRect.l;          //20
    lData[i++]=lRect.b;
    lData[i++]=0;
    lData[i++]=0;
    lData[i++]=lRect.l+lS.x;     //21
    lData[i++]=lRect.b;
    lData[i++]=lSC.x;
    lData[i++]=0;
    lData[i++]=lRect.r-lS.x;     //22
    lData[i++]=lRect.b;
    lData[i++]=lSC.x;
    lData[i++]=0;
    lData[i++]=lRect.r;          //23
    lData[i++]=lRect.b;
    lData[i++]=0;
    lData[i++]=0;

    glEnableVertexAttribArray(3);
    glVertexAttribPointer(3,2,GL_FLOAT,GL_FALSE,4*sizeof(GLfloat),lData+2);
    glVertexAttribPointer(0,2,GL_FLOAT,GL_FALSE,4*sizeof(GLfloat),lData);

    uint32_t lElements[]={
        0,6,7,1,        1,7,8,2,        2,8,9,3,
        0,4,5,6,        4,12,13,5,      12,20,14,13,
        14,20,21,15,    15,21,22,16,    16,22,23,17,
        17,23,19,18,    18,19,11,10,    10,11,3,9
    };
    glDrawElements(GL_QUADS,48,GL_UNSIGNED_INT,lElements);
    glDisableVertexAttribArray(3);
}

void CShadowDecoration::PaintBaseLine()
{
    ///\todo this
    /*
    CPoint_d lPoint(-mClientSize.x/2-GetTotalExtent().l,
                    -mClientSize.y-GetTotalExtent().t);

    CGLMatrix lMatrix=gRoot->GetShadowTexture()->mMatrix;
    lMatrix.xx=1.0/mClientSize.x;
    lMatrix.yy=1.0/mClientSize.y;
    lMatrix.x0-=lPoint.x*lMatrix.xx;
    lMatrix.y0-=lPoint.y*lMatrix.yy;

    gRoot->GetShadowTexture()->Enable(false);
    CRect_d lDecoRect=CRect(lPoint,mClientSize+GetTotalExtent().Size());
    CGL::DrawRect(lDecoRect,lMatrix);
    gRoot->GetShadowTexture()->Disable();
    */
}

CRect_i CShadowDecoration::GetTotalExtent()
{
    return CRect_i(-25,-15,25,25);
}

CRect_i CShadowDecoration::GetFrameExtent()
{
    return CRect_i(0,0,0,0);
}

/*namespace bwm*/ } /*namespace buola*/ }
